﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace CloudShot.Utils
{
  public class ButtonAppearanceTheme
  {
    public Color BorderColor { get; set; }
    public int BorderSize { get; set; }
    public Color CheckedBackColor { get; set; }
    public Color MouseOverBackColor { get; set; }
    public Color MouseDownBackColor { get; set; }
    public List<Control> Ignore { get; private set; }

    public ButtonAppearanceTheme()
    {
      Ignore = new List<Control>();
    }

    public void ApplyTo(Control control)
    {
      if (!Ignore.Contains(control))
      {
        if (control is Button)
          ApplyToButton((Button)control);

        if (control is CheckBox)
          ApplyToCheckBox((CheckBox)control);

        if (control is RadioButton)
          ApplyToRadioButton((RadioButton)control);  
      }      

      foreach (Control childControl in control.Controls)
      {
        ApplyTo(childControl);
      }
    }

    #region Private Methods

    private void ApplyToButton(Button button)
    {
      ApplyToButtonBase(button);
    }

    private void ApplyToCheckBox(CheckBox checkBox)
    {
      ApplyToButtonBase(checkBox);

      checkBox.CheckedChanged -= OnCheckedChanged;
      checkBox.CheckedChanged += OnCheckedChanged;
    }

    private void ApplyToRadioButton(RadioButton radioButton)
    {
      ApplyToButtonBase(radioButton);

      radioButton.CheckedChanged -= OnCheckedChanged;
      radioButton.CheckedChanged += OnCheckedChanged;
    }

    private void ApplyToButtonBase(ButtonBase buttonBase)
    {
      buttonBase.FlatStyle = FlatStyle.Flat;
      buttonBase.FlatAppearance.BorderColor = BorderColor;
      buttonBase.FlatAppearance.BorderSize = BorderSize;
      buttonBase.FlatAppearance.CheckedBackColor = CheckedBackColor;
      buttonBase.FlatAppearance.MouseOverBackColor = MouseOverBackColor;
      buttonBase.FlatAppearance.MouseDownBackColor = MouseDownBackColor;

      buttonBase.MouseDown -= OnButtonMouseDown;
      buttonBase.MouseUp -= OnButtonMouseUp;

      buttonBase.MouseDown += OnButtonMouseDown;
      buttonBase.MouseUp += OnButtonMouseUp;
    }

    #endregion

    #region Event Handlers

    private void OnButtonMouseDown(object sender, MouseEventArgs e)
    {
      var button = sender as ButtonBase;
      if (button == null)
        return;

      button.FlatAppearance.BorderSize = 1;
    }

    private void OnButtonMouseUp(object sender, MouseEventArgs e)
    {
      UpdateBorder(sender as ButtonBase);
    }

    private void OnCheckedChanged(object sender, EventArgs e)
    {
      UpdateBorder(sender as ButtonBase);
    }

    private static void UpdateBorder(ButtonBase button)
    {
      if (button == null)
        return;

      int borderSize = 0;

      if (button is CheckBox)
      {
        borderSize = ((CheckBox)button).Checked ? 1 : 0;
      }
      else if (button is RadioButton)
      {
        borderSize = ((RadioButton)button).Checked ? 1 : 0;
      }

      button.FlatAppearance.BorderSize = borderSize;
    }

    #endregion
  }
}